﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Web.UI.WebControls;
using System.Drawing;

public class MatrixFlat
{
    #region member variables - private
    private int SlabId = 0;
    private int rowCount = 0;
    private int colCount = 0;
    private DataTable dt;
    private TextBox[,] tbSlab;
    private DataTable flatDt;
    #endregion

    #region getters
    public int getRowCount() { return rowCount; }
    public int getColumnCount() { return colCount; }
    public int getSlabId() { return SlabId; }
    public DataTable getMatrix2DT() { return dt; }
    public TextBox[,] getMatrix2TB() { return tbSlab; }
    #endregion

    #region constuctor - new matrix
    //this is new slab id create request
    public MatrixFlat(int si, int rows, int columns)
    {
        //set dimensions 
        SlabId = si;
        rowCount = rows;
        colCount = columns;

        //create blank
        Initialize2D();
        createFlat();
    }

    //set all values to zero
    private void Initialize2D()
    {
        dt = new DataTable();
        tbSlab = new TextBox[rowCount + 1, colCount + 1];

        //create columns
        for (int i = 0; i <= colCount; i++)
            dt.Columns.Add("C" + i.ToString());
        //create rows
        for (int i = 0; i <= rowCount; i++)
            dt.Rows.Add("R" + i.ToString());

        //set zero values
        for (int i = 0; i <= rowCount; i++)
        {
            for (int j = 0; j <= colCount; j++)
            {
                Boolean isHeader = false;
                if (colCount == 1)
                    isHeader = (j == 0);
                else
                    isHeader = ((i == 0) || (j == 0));
                tbSlab[i, j] = getTextBox(isHeader);
                tbSlab[i, j].Text = "0";
                dt.Rows[i][j] = "0";
            }
        }

        dt.AcceptChanges();
    }

    //create flat with zero values
    private void createFlat()
    {
        flatDt = new DataTable();

        //create columns
        flatDt.Columns.Add("SlabId");
        flatDt.Columns.Add("RowNo");
        flatDt.Columns.Add("ColumnNo");
        flatDt.Columns.Add("Value");

        //populate datatable with default values
        for (int i = 0; i <= rowCount; i++)
        {
            for (int j = 0; j <= colCount; j++)
            {
                DataRow dr = flatDt.NewRow();
                dr["SlabID"] = SlabId;
                dr["RowNo"] = i;
                dr["ColumnNo"] = j;
                dr["Value"] = 0;
                flatDt.Rows.Add(dr);
            }
        }
        flatDt.AcceptChanges();
        //GlobalMethods.uploadDT2DB(dt, "SlabValues");
    }
    #endregion

    #region constructor - existing matrix
    //this is retrieval request
    public MatrixFlat(int si)
    {
        SlabId = si;
        RetrieveDimension();
        RetrieveDBValues();
        Initialize2D();
        ConvertFlat2Matrix();
    }

    //get dimension of existing matrix
    private void RetrieveDimension()
    {
        string rowCmd = "Select Max(RowNo) from SlabValues where SlabId = '" + SlabId.ToString() + "'";
        string colCmd = "Select Max(ColumnNo) from SlabValues where SlabId = '" + SlabId.ToString() + "'";

        string rows = DataBaseMethods.ExecuteScalar(rowCmd);
        string cols = DataBaseMethods.ExecuteScalar(colCmd);

        try
        {
            rowCount = Convert.ToInt32(rows);
            colCount = Convert.ToInt32(cols);
        }
        catch (Exception)
        {
            throw new Exception("Slab does not exist.");
        }

        if ((rowCount < 1) || (colCount < 1))
            throw new Exception("Invalid Slab Dimensions");
    }

    //get flat values
    private void RetrieveDBValues()
    {
        //select command
        string selectCmd = "Select SlabId, RowNo, ColumnNo, Value from SlabValues where SlabId = '" + SlabId.ToString() + "' Order By RowNo, ColumnNo ";

        //get slab values - flat structure
        flatDt = DataBaseMethods.ExecuteSelectQuery(selectCmd);
    }

    private TextBox getTextBox(bool header)
    {
        TextBox tb = new TextBox();
        tb.Height = 25;
        tb.Width = 60;
        tb.BorderWidth = 2;
        if (header) tb.BackColor = Color.Aqua;
        return tb;
    }
    #endregion

    #region converts matrix v/s flat
    //convert flat to matrix
    private void ConvertFlat2Matrix()
    {
        foreach (DataRow dr in flatDt.Rows)
        {
            dt.Rows[Convert.ToInt32(dr[1].ToString())][Convert.ToInt32(dr[2].ToString())] = dr[3].ToString();
            tbSlab[Convert.ToInt32(dr[1].ToString()), Convert.ToInt32(dr[2].ToString())].Text = dr[3].ToString();
        }
    }

    public void convertMatrix2Flat()
    {
        foreach (DataRow dr in flatDt.Rows)
        {
            int row = Convert.ToInt32(dr.Table.Rows[0][1].ToString());
            int col = Convert.ToInt32(dr.Table.Rows[0][2].ToString());
            dr.Table.Rows[0][3] = dt.Rows[row][col].ToString();
            //tbSlab[Convert.ToInt32(dr[1].ToString()), Convert.ToInt32(dr[2].ToString())].Text = dr[3].ToString();
        }
    }
    #endregion

    #region update operations
    public void updateDB()
    {
        DataBaseMethods.uploadDT2DB(flatDt, "SlabValues");
    }

    //uplodate matrix from datatable
    public void updateMatrix(DataTable inputdt)
    {
        for (int i = 0; i <= rowCount; i++)
        {
            for (int j = 0; j <= colCount; j++)
            {
                tbSlab[i, j].Text = inputdt.Rows[i][j].ToString();
                dt.Rows[i][j] = inputdt.Rows[i][j].ToString();
            }
        }
        convertMatrix2Flat();
    }

    //uplodate matrix from text boxes
    public void updateMatrix(TextBox[,] inputTb)
    {
        for (int i = 0; i <= rowCount; i++)
        {
            for (int j = 0; j <= colCount; j++)
            {
                tbSlab[i, j].Text = inputTb[i, j].ToString();
                dt.Rows[i][j] = inputTb[i, j].ToString();
            }
        }
        convertMatrix2Flat();
    }
    #endregion

}
